﻿using System.Collections.Generic;
using System.Linq;
using System.Web.Mvc;
using NGM.Portlets.Providers;
using Orchard;
using Orchard.ContentManagement.MetaData;
using Orchard.ContentManagement.MetaData.Models;
using Orchard.Core.Contents.Settings;
using Orchard.DisplayManagement;
using Orchard.Localization;
using Orchard.Mvc.Filters;
using Orchard.UI.Admin;
using Orchard.Widgets.Services;

namespace NGM.Portlets.Toolbar {
    public class ToolbarFilter : FilterProvider, IResultFilter {
        private readonly IOrchardServices _orchardServices;
        private readonly IWidgetsService _widgetsService;
        private readonly IWorkContextAccessor _workContextAccessor;
        private readonly dynamic _shapeFactory;
        private readonly IContentDefinitionManager _contentDefinitionManager;
        private readonly IWidgetsService _widgetService;
        private readonly IEnumerable<IPortletNavigationProvider> _portletNavigationProviders;

        public ToolbarFilter(
            IOrchardServices orchardServices,
            IWidgetsService widgetsService,
            IWorkContextAccessor workContextAccessor,
            IShapeFactory shapeFactory,
            IContentDefinitionManager contentDefinitionManager,
            IWidgetsService widgetService,
            IEnumerable<IPortletNavigationProvider> portletNavigationProviders) {
            _orchardServices = orchardServices;
            _widgetsService = widgetsService;
            _workContextAccessor = workContextAccessor;
            _shapeFactory = shapeFactory;
            _contentDefinitionManager = contentDefinitionManager;
            _widgetService = widgetService;
            _portletNavigationProviders = portletNavigationProviders;

            T = NullLocalizer.Instance;
        }

        public Localizer T { get; set; }

        public void OnResultExecuting(ResultExecutingContext filterContext) {
            if (filterContext.RequestContext.HttpContext.Request.IsAjaxRequest())
                return;

            if (AdminFilter.IsApplied(filterContext.RequestContext))
                return;

            var enableHiddenZones = EnableHiddenZones(filterContext);

            var creatableTypes = GetCreatableTypes();

            foreach (var portletNavigationProvider in _portletNavigationProviders) {
                
            }

            //var widgetTypes = _widgetsService.GetWidgetTypes();
            _workContextAccessor
                .GetContext(filterContext)
                .Layout
                .Zones["Body"]
                .Add(
                _shapeFactory.Toolbar(ContentTypes: creatableTypes, WidgetTypes: "", EnableHiddenZones: enableHiddenZones), ":before");
        }

        private bool EnableHiddenZones(ResultExecutingContext filterContext) {
            var item = filterContext.Controller.TempData["enablehiddenzones"];

            if (item == null) return false;

            var enableHiddenZones = (bool)item;
            
            if (!enableHiddenZones)
                return false;

            var zones = _widgetsService.GetZones(_orchardServices.WorkContext.CurrentTheme);

            var hiddenZones = zones
                .Where(zone => _workContextAccessor.GetContext(filterContext).Layout.Zones[zone] == null)
                .ToList();
            
            var layout = _workContextAccessor.GetContext(filterContext).Layout;
            foreach (var availableZone in hiddenZones) {
                layout.Zones[availableZone].Add(string.Format("{0} {1}", availableZone, T("(Zone)")));
            }
            return true;
        }

        private IEnumerable<ContentTypeDefinition> GetCreatableTypes() {
            return _contentDefinitionManager
                .ListTypeDefinitions()
                .Where(ctd => 
                    ctd.Settings.GetModel<ContentTypeSettings>().Creatable 
                    && ctd.Parts.Any(o => o.PartDefinition.Name == "AutoroutePart"));
        }

        public void OnResultExecuted(ResultExecutedContext filterContext) { }
    }
}